package org.springframework.security.authentication;

import org.springframework.security.core.userdetails.UserCache;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.cache.NullUserCache;
import org.springframework.util.Assert;

/**
 * @author Dillon
 * @date 2024/7/1
 * @slogan 致敬大师 致敬未来的你
 * @desc 为查询到自定义用户提供缓存功能
 */
public class CachingUserDetailsService implements UserDetailsService {

	/**
	 * 自定义用户缓存实现
	 * 默认不缓存
	 */
	private UserCache userCache = new NullUserCache();

	/**
	 * 代理自定义用户查询实现类
	 */
	private final UserDetailsService delegate;

	/**
	 * 构造函数
	 *
	 * @param delegate 代理自定义用户查询实现类
	 */
	public CachingUserDetailsService(UserDetailsService delegate) {
		this.delegate = delegate;
	}

	/**
	 * 获取用户缓存实现类
	 *
	 * @return 用户缓存实现类
	 */
	public UserCache getUserCache() {
		return this.userCache;
	}

	/**
	 * 设置用户缓存实现类
	 *
	 * @param userCache 用户缓存实现类
	 */
	public void setUserCache(UserCache userCache) {
		this.userCache = userCache;
	}

	/**
	 * 通过用户名获取自定义用户 优先从缓存获取
	 *
	 * @param username 用户名
	 * @return 自定义用户
	 */
	@Override
	public UserDetails loadUserByUsername(String username) {
		UserDetails user = this.userCache.getUserFromCache(username);
		if (user == null) {
			user = this.delegate.loadUserByUsername(username);
		}
		Assert.notNull(user, () -> "UserDetailsService " + this.delegate + " 通过用户名 " + username + ". " + "未查到自定义用户对象");
		this.userCache.putUserInCache(user);
		return user;
	}

}
